home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cocktail / rpp.lha / rpp / src / rpp.rex < prev    next >
OS/2 REXX Batch file  |  1992-08-18  |  8KB  |  312 lines

  1. EXPORT {
  2. FROM    Positions    IMPORT    tPosition;
  3.  
  4. TYPE tScanAttribute    = RECORD Position: tPosition; END;
  5.  
  6. VAR InfoFileName    : ARRAY [0..255] OF CHAR;
  7. }
  8.  
  9. GLOBAL {
  10. FROM    System        IMPORT    GetArgument,    GetArgCount;
  11. FROM    Strings        IMPORT    tString,    AssignEmpty,    Append,
  12.                 Concatenate,    Length,        Char,
  13.                 IntToString,    StringToArray,    WriteS,
  14.                 ReadL,        WriteL,        IsEqual,
  15.                 ArrayToString;
  16. FROM    StringMem    IMPORT    tStringRef,    PutString,    GetString;
  17. FROM    Idents        IMPORT    tIdent,        NoIdent,    MakeIdent,
  18.                 MaxIdent,    InitIdents;
  19. FROM     IO        IMPORT    StdInput,    StdOutput,    StdError,
  20.                 tFile,        ReadOpen,    ReadClose,
  21.                 ReadI,        ReadC,        WriteC,
  22.                 WriteI,        WriteNl,    EndOfFile,
  23.                 CloseIO;
  24.  
  25. CONST    MissingInfo    = "rpp: cannot access file <Scanner>.rpp";
  26.  
  27. VAR    Level        : CARDINAL;
  28.     StartString    : tString;
  29.     TheWord        : tString;
  30.     IsCollecting    : BOOLEAN;
  31.     BothFlag    : BOOLEAN;
  32.     Returning    : BOOLEAN;
  33.     InsText        : tString;
  34.     InfoFile    : tFile;
  35.     LastIdent    : tIdent;
  36.     TokenCode    : ARRAY [0..1023] OF SHORTCARD;
  37.     TokenSelector    : ARRAY [0..1023] OF tStringRef;
  38.     Not1, Not2, Not3: tString;
  39.     Any1, Any2, Any3: tString;
  40.     Argument    : ARRAY [0 .. 127] OF CHAR;
  41.     i        : SHORTCARD;
  42.     Language    : (Modula, C);
  43.  
  44. PROCEDURE Skip;
  45. BEGIN
  46.   REPEAT
  47.     ReadL (InfoFile, TheWord);
  48.   UNTIL (Length (TheWord) = 2) AND (Char (TheWord, 1) = '%') AND (Char (TheWord, 2) = '%');
  49. END Skip;
  50.  
  51. PROCEDURE DoText;
  52. BEGIN
  53.   IF NOT IsCollecting THEN yyEcho;
  54.   ELSIF Level > 0 THEN GetWord (TheWord); Concatenate (InsText, TheWord);
  55.   END;
  56. END DoText;
  57.  
  58. PROCEDURE DoIdent;
  59. VAR i: tIdent;
  60. BEGIN
  61.   GetWord (TheWord);
  62.   i := MakeIdent (TheWord);
  63.   IF i <= LastIdent THEN
  64.     IF Returning THEN
  65.       IntToString (TokenCode [i], TheWord);
  66.     ELSE
  67.       GetString (TokenSelector [i], TheWord);
  68.     END;
  69.     IF IsCollecting THEN
  70.       Concatenate (InsText, TheWord);
  71.     ELSE
  72.       WriteS (StdOutput, TheWord);
  73.     END;
  74.   ELSE
  75.     IF IsCollecting THEN
  76.       Concatenate (InsText, TheWord);
  77.     ELSE
  78.       yyEcho;
  79.     END;
  80.   END;
  81. END DoIdent;
  82.  
  83. PROCEDURE CopyText;
  84. BEGIN
  85.   LOOP
  86.     ReadL (InfoFile, TheWord);
  87.     IF (Length (TheWord) = 2) AND (Char (TheWord, 1) = '%') AND (Char (TheWord, 2) = '%') THEN EXIT; END;
  88.     WriteL (StdOutput, TheWord);
  89.   END;
  90. END CopyText;
  91.  
  92. PROCEDURE GenPosition;
  93. BEGIN
  94.   CASE Language OF
  95.   | Modula: IO.WriteS (StdOutput, "FROM Positions IMPORT tPosition;");
  96.   | C      : IO.WriteS (StdOutput, '# include "Positions.h"');
  97.   ELSE
  98.   END;
  99.   WriteNl (StdOutput);
  100. END GenPosition;
  101.  
  102. PROCEDURE GenScanAttr;
  103. BEGIN
  104.   InfoFile := ReadOpen (InfoFileName);
  105.   ReadL (InfoFile, TheWord);
  106.   CopyText;
  107.   ReadClose (InfoFile);
  108. END GenScanAttr;
  109.  
  110. PROCEDURE GenErrorAttr;
  111. BEGIN
  112.   InfoFile := ReadOpen (InfoFileName);
  113.   Skip;
  114.   CopyText;
  115.   ReadClose (InfoFile);
  116. END GenErrorAttr;
  117.  
  118. PROCEDURE ReadIdents;
  119. VAR    t, i    : INTEGER;
  120.     c    : CHAR;
  121.     Ident    : tIdent;
  122.     Selector: ARRAY [0..255] OF CHAR;
  123.     String    : tString;
  124. BEGIN
  125.   InfoFile := ReadOpen (InfoFileName);
  126.   IF InfoFile < 0 THEN
  127.      IO.WriteS (StdError, MissingInfo); WriteNl (StdError); CloseIO; HALT;
  128.   END;
  129.   ReadL (InfoFile, TheWord);
  130.   CASE Char (TheWord, 1) OF
  131.   | 'm' : Language := Modula;
  132.   | 'c' : Language := C;
  133.   ELSE
  134.   END;
  135.   Skip;
  136.   Skip;
  137.   WHILE NOT EndOfFile (InfoFile) DO
  138.     t := ReadI (InfoFile);
  139.     c := ReadC (InfoFile);
  140.     c := ReadC (InfoFile);
  141.     c := ReadC (InfoFile);
  142.     i := 0;
  143.     REPEAT
  144.        Selector [i] := ReadC (InfoFile);
  145.        INC (i);
  146.     UNTIL Selector [i-1] = ' ';
  147.     Selector [i-1] := 0C;
  148.     ArrayToString (Selector, String);
  149.     ReadL (InfoFile, TheWord);
  150.     Ident := MakeIdent (TheWord);
  151.     TokenCode [Ident] := t;
  152.     TokenSelector [Ident] := PutString (String);
  153.   END;
  154.   ReadClose (InfoFile);
  155.   LastIdent := MaxIdent ();
  156. END ReadIdents;
  157.  
  158. PROCEDURE InsertRules;
  159. VAR    Code    : CARDINAL;
  160.     c, Ch    : CHAR;
  161.     Selector: ARRAY [0..255] OF CHAR;
  162.     i    : CARDINAL;
  163.  
  164.   PROCEDURE WriteIdent (VAR TheWord : tString);
  165.   VAR    s    : ARRAY [0..255] OF CHAR;
  166.     j    : CARDINAL;
  167.   BEGIN
  168.     StringToArray (TheWord, s);
  169.     s [Length (TheWord)] := "'";
  170.     IF NOT BothFlag AND (
  171.        IsEqual (TheWord, Not1) OR IsEqual (TheWord, Not2) OR IsEqual (TheWord, Not3) OR
  172.        IsEqual (TheWord, Any1) OR IsEqual (TheWord, Any2) OR IsEqual (TheWord, Any3)) THEN
  173.       WriteC (StdOutput, "\");
  174.     END;
  175.     IF (s [0] = "'") OR (s [0] = '"') THEN j := 1; ELSE j := 0; END;
  176.     REPEAT
  177.       IF BothFlag THEN
  178.         CASE s [j] OF
  179.       'a'..'z' :
  180.         WriteC (StdOutput, "{");
  181.         WriteC (StdOutput, s [j]);
  182.         WriteC (StdOutput, CAP (s [j]));
  183.         WriteC (StdOutput, "}");
  184.     | 'A'..'Z' :
  185.         WriteC (StdOutput, "{");
  186.         WriteC (StdOutput, CHR (ORD (s [j]) - ORD ('A') + ORD ('a')));
  187.         WriteC (StdOutput, s [j]);
  188.         WriteC (StdOutput, "}");
  189.     | '0'..'9', '_' :
  190.         WriteC (StdOutput, s [j]);
  191.     ELSE
  192.       WriteC (StdOutput, "\");
  193.       WriteC (StdOutput, s [j]);
  194.     END;
  195.       ELSE
  196.     CASE s [j] OF
  197.       '0'..'9', 'A'..'Z', 'a'..'z', '_' : WriteC (StdOutput, s [j]);
  198.     ELSE
  199.       WriteC (StdOutput, "\");
  200.       WriteC (StdOutput, s [j]);
  201.     END;
  202.       END;
  203.       INC (j);
  204.     UNTIL (s [j] = '"') OR (s [j] = "'");
  205.   END WriteIdent;
  206.  
  207. BEGIN
  208.   InfoFile := ReadOpen (InfoFileName);
  209.   Skip;
  210.   Skip;
  211.   WHILE NOT EndOfFile (InfoFile) DO
  212.     Code := ReadI (InfoFile);
  213.     c := ReadC (InfoFile);
  214.     Ch := ReadC (InfoFile);
  215.     c := ReadC (InfoFile);
  216.     i := 0;
  217.     REPEAT
  218.        Selector [i] := ReadC (InfoFile);
  219.        INC (i);
  220.     UNTIL Selector [i-1] = ' ';
  221.     Selector [i-1] := 0C;
  222.     ReadL (InfoFile, TheWord);
  223.     IF Ch # 'S' THEN
  224.        WriteS (StdOutput, StartString);
  225.        WriteIdent (TheWord);
  226.        WriteC (StdOutput, 11C);
  227.        IO.WriteS (StdOutput, ": { ");
  228.        WriteS (StdOutput, InsText);
  229.        CASE Language OF
  230.        | Modula    : IO.WriteS (StdOutput, "RETURN ");
  231.        | C    : IO.WriteS (StdOutput, "return ");
  232.        END;
  233.        WriteI (StdOutput, Code, 0);
  234.        IO.WriteS (StdOutput, "; }");
  235.        WriteNl (StdOutput);
  236.      END;
  237.   END;
  238.   ReadClose (InfoFile);
  239. END InsertRules;
  240. }
  241.  
  242. BEGIN {
  243. InfoFileName := "Scanner.rpp";
  244. Language := Modula;
  245. IF GetArgCount () > 1 THEN GetArgument (1, ScanTabName); END;
  246. IF GetArgCount () > 2 THEN GetArgument (2, InfoFileName); END;
  247. IsCollecting := FALSE;
  248. InitIdents;
  249. ReadIdents;
  250. AssignEmpty (InsText);
  251. AssignEmpty (StartString);
  252. ArrayToString ("NOT", Not1);
  253. ArrayToString ("'NOT'", Not2);
  254. ArrayToString ('"NOT"', Not3);
  255. ArrayToString ("ANY", Any1);
  256. ArrayToString ("'ANY'", Any2);
  257. ArrayToString ('"ANY"', Any3);
  258. }
  259.  
  260. DEFINE    letter    = {A-Z a-z _} .
  261.     digit    = {0-9} .
  262.     StartCh    = - {#\n} .
  263.     StrCh1    = - {'\n} .
  264.     StrCh2    = - {"\n} .
  265.     WS    = {\ \t} + .
  266.  
  267. START    Return, Start, Action, Rules, Set
  268.  
  269. RULE
  270.  
  271. #STD#     \{                :- { yyStart (Action); yyEcho; Level := 1; }
  272. #STD#     DEFINE | RULE            :- { yyStart (Rules); yyEcho; }
  273.  
  274. #Rules#     \" StrCh2 + \"                :- { DoText; }
  275. #Rules#     INSERT WS RULES            :- { yyStart (Start); BothFlag := FALSE; }
  276. #Rules#     INSERT WS RULES WS CASE\-INSENSITIVE    :- { yyStart (Start); BothFlag := TRUE; }
  277. #Rules#     \: | \:\-                :- { yyStart (Action); yyEcho; Level := 0; }
  278. #Rules#     \{                    :- { yyStart (Set); yyEcho; }
  279.  
  280. #Set#     \}                :- { yyPrevious; yyEcho; }
  281.  
  282. #Start#  \n                :- { yyPrevious; InsertRules; }
  283. #Start#     "NOT" ? WS ? \# StartCh + \#    :- { yyPrevious; GetWord (StartString); InsertRules; }
  284. #Start#  "NOT" ? WS ? \# StartCh + \# / WS ? \{    :- { GetWord (StartString);
  285.                  yyStartState := Action; Level := 0; IsCollecting := TRUE; }
  286. #Start#  WS ? / \{    :- { yyStartState := Action; Level := 0; IsCollecting := TRUE; }
  287.  
  288. #Action# INSERT WS tPosition        :- { GenPosition; }
  289. #Action# INSERT WS tScanAttribute    :- { GenScanAttr; }
  290. #Action# INSERT WS ErrorAttribute    :- { GenErrorAttr; }
  291.  
  292. #Action# \{                :- { DoText; INC (Level); }
  293. #Action# \}                :- { DEC (Level);
  294.                          IF Level > 0 THEN
  295.                            DoText;
  296.                          ELSE
  297.                            yyPrevious;
  298.                            IF IsCollecting THEN
  299.                          InsertRules; IsCollecting := FALSE;
  300.                            ELSE
  301.                          yyEcho;
  302.                            END;
  303.                          END; }
  304.  
  305. #Action# Attribute\.        :- { yyStartState := Return; DoText; Returning := FALSE; }
  306. #Action# RETURN | return    :- { yyStartState := Return; DoText; Returning := TRUE; }
  307.  
  308. #Return# (letter | digit) *        :- { yyStartState := Action; DoIdent; }
  309. #Return# ' StrCh1 + ' | \" StrCh2 + \"    :- { yyStartState := Action; DoIdent; }
  310.  
  311.      \\ ? ANY, WS, \n         :- { DoText; }
  312.